﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace Utility2DLibrary
{
    public abstract class zVisualObject : TexturedPrimitivePolyShape
    {
        private float mouseOver;
        [ContentSerializerIgnore]
        public float MouseOver
        {
            get { return mouseOver; }
            set { mouseOver = value; }
        }

        private Effect shaderEffect;
        [ContentSerializerIgnore]
        public Effect ShaderEffect
        {
            get { return shaderEffect; }
            set { shaderEffect = value; }
        }

        private string shaderEffectFile;
        public string ShaderEffectFile
        {
            get{return shaderEffectFile;}
            set{shaderEffectFile=value;}
        }
        private Point position;
        public Vector2 PositionVector
        {
            get { return position.ToVector2(); }
            set { position = new Point(value); }
        }
        private float orientation;
        public float Orientation
        {
            get { return orientation; }
            set { orientation = value; }
        }
        public zVisualObject(Effect shader,Texture2D texture,Point InitPosition, float InitOrientation) : base(texture)
        {
            shaderEffect = shader;
            position = InitPosition;
            orientation = InitOrientation;
        }
        public void Draw(SpriteBatch spritebatch, Matrix ViewProjection)
        {
            List<MassPoint> translatedPointList = this.TransformPolyLinesToWorldCoords(spritebatch);
            this.DrawPrimitive(spritebatch, translatedPointList, ViewProjection);
        }
        private List<MassPoint> TransformPolyLinesToWorldCoords(SpriteBatch spritebatch)
        {
            List<MassPoint> translatedPointList = new List<MassPoint>();

            RectangleF transBoundingBox = TranslateLocalBoundingBox();
            Point positionOffset = new Point(position.X - transBoundingBox.Left, position.Y + transBoundingBox.Top);
            Point positionOffsetLR = new Point(position.X - transBoundingBox.Right, position.Y + transBoundingBox.Bottom);

            Point transOrigin = TranslateCenterOfMass(positionOffset);

            for (int i = 0; i < base.PrimitivePoints.Count; i++)
            {
                MassPoint tp = new MassPoint(base.PrimitivePoints[i].FlipY().TranslateAndTransform(base.scale, positionOffset.ToVector2(), orientation, transOrigin),0);
                translatedPointList.Add(tp);
            }
            return translatedPointList;
        }
        private RectangleF TranslateLocalBoundingBox()
        {
            Point upperLeft = new Point(base.LocalBoundingBox.Left, base.LocalBoundingBox.Top);
            Point lowerRight = new Point(base.LocalBoundingBox.Right, base.LocalBoundingBox.Bottom);

            upperLeft.Scale(scale);
            lowerRight.Scale(scale);

            upperLeft.FlipY().Translate(position.ToVector2());
            lowerRight.FlipY().Translate(position.ToVector2());

            return new RectangleF(upperLeft,lowerRight);
        }
        private Point TranslateCenterOfMass(Point positionOffset)
        {
            Point transCenter = new Point(centerOfMass.FlipY());
            transCenter.Scale(scale);
            transCenter.Translate(positionOffset.ToVector2());
            return transCenter;
        }
        private void DrawPrimitive(SpriteBatch spritebatch,List<MassPoint> massVertexList,Matrix ViewProjection)
        {
            VertexPositionColorTexture[] vertexList = new VertexPositionColorTexture[massVertexList.Count];
            int[] indexList = new int[massVertexList.Count];
            Vector2[] uv = new Vector2[3];
            uv[0] = new Vector2(0, 1);
            uv[1] = new Vector2(1, 0);
            uv[2] = new Vector2(1, 1);
            
            for(int i=0;i<massVertexList.Count;i++)
            {
                indexList[i]=i;
                vertexList[i].Color=Color.White;
                Vector2 vecXY = massVertexList[i].ToVector2();
                vertexList[i].Position = new Vector3(vecXY.X,vecXY.Y,0);
                vertexList[i].TextureCoordinate = PrimitivePoints[i].ToVector2();
            }
            int numPrimitives = 1 + (vertexList.Length - 3);
            shaderEffect.Parameters["matViewProjection"].SetValue(ViewProjection);
            shaderEffect.Parameters["texureMap"].SetValue(PolyTexture);
            shaderEffect.Parameters["selected"].SetValue(mouseOver);
            shaderEffect.Begin();
            EffectPass pass = shaderEffect.Techniques[0].Passes[0];
            pass.Begin();
            spritebatch.GraphicsDevice.VertexDeclaration = new VertexDeclaration(spritebatch.GraphicsDevice, VertexPositionColorTexture.VertexElements);
            spritebatch.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleStrip, vertexList, 0, indexList.Length - 1, indexList, 0, numPrimitives);
            pass.End();
            shaderEffect.End();

        }
    }
}
